﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CPPEI.Coolzon.UI.PetroleumDataPartLib
{
    /// <summary>
    /// CircularProgress.xaml 的交互逻辑
    /// </summary>
    [System.ComponentModel.DisplayName("管网油罐2")]
    [XPartIcon("pack://application:,,,/CPPEI.Coolzon.UI.PetroleumDataPartLib;component/Images/PartIcons/管网油罐.png")]
    public partial class CircularProgress : DataItemPart
    {
        #region XProperty
        [Category("其他")]
        [DisplayName("底图")]
        [Description("BaseImageSource")]
        [Editor(typeof(UI.XProperty.Editors.XImageSourceFileEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "BaseImageSource", "底图")]
        public ImageSourceFile XBaseImageSource
        {
            get
            {
                return _XBaseImageSource;
            }
            set
            {
                _XBaseImageSource = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("进度")]
        [Description("ProgressFill")]
        [Editor(typeof(UI.XProperty.Editors.XBrushEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "ProgressFill", "进度")]
        public BrushEx XProgressFill
        {
            get
            {
                return _XProgressFill;
            }
            set
            {
                _XProgressFill = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("前景图")]
        [Description("FrontImageSource")]
        [Editor(typeof(UI.XProperty.Editors.XImageSourceFileEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "FrontImageSource", "前景图")]
        public ImageSourceFile XFrontImageSource
        {
            get
            {
                return _XFrontImageSource;
            }
            set
            {
                _XFrontImageSource = value;
                Refresh();
            }
        }
        //[XProperty(XPropertyCategory.Other, "Value", "进度值")]
        //public double XValue
        //{
        //    get
        //    {
        //        return _XValue;
        //    }
        //    set
        //    {
        //        _XValue = value;
        //        ApplyXProperty();
        //    }
        //}
        [Category("其他")]
        [DisplayName("最小值")]
        [Description("Minimum")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "Minimum", "最小值")]
        public double XMinimum
        {
            get
            {
                return _XMinimum;
            }
            set
            {
                _XMinimum = value;
                Refresh();
            }
        }
        [Category("其他")]
        [DisplayName("最大值")]
        [Description("Maximum")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "Maximum", "最大值")]
        public double XMaximum
        {
            get
            {
                return _XMaximum;
            }
            set
            {
                _XMaximum = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("文本格式化")]
        [Description("TextFormat")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "TextFormat", "文本格式化")]
        public string XTextFormat
        {
            get
            {
                return _XTextFormat;
            }
            set
            {
                _XTextFormat = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("字体大小")]
        [Description("FontSize")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "FontSize", "字体大小")]
        public double? XFontSize
        {
            get
            {
                return _XFontSize;
            }
            set
            {
                _XFontSize = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("字体位置")]
        [Description("TextAlign")]
        [Editor(typeof(UI.XProperty.Editors.XTextAlignmentEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "TextAlign", "字体位置")]
        public TextAlignment XTextAlign
        {
            get
            {
                return _XTextAlign;
            }
            set
            {
                _XTextAlign = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("字体水平位置")]
        [Description("TextHAlign")]
        [Editor(typeof(UI.XProperty.Editors.XHorizontalAlignmentEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "TextHAlign", "字体水平位置")]
        public HorizontalAlignment XTextHAlign
        {
            get
            {
                return _XTextHAlign;
            }
            set
            {
                _XTextHAlign = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("字体垂直位置")]
        [Description("TextVAlign")]
        [Editor(typeof(UI.XProperty.Editors.XVerticalAlignmentEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "TextVAlign", "字体垂直位置")]
        public VerticalAlignment XTextVAlign
        {
            get
            {
                return _XTextVAlign;
            }
            set
            {
                _XTextVAlign = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("文本边距")]
        [Description("TextMargin")]
        [Editor(typeof(UI.XProperty.Editors.XThicknessEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "TextMargin", "文本边距")]
        public Thickness XTextMargin
        {
            get
            {
                return _XTextMargin;
            }
            set
            {
                _XTextMargin = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("字体样式")]
        [Description("FontFamily")]
        [Editor(typeof(UI.XProperty.Editors.XFontFamilyEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "FontFamily", "字体样式")]
        public FontFamily XFont
        {
            get
            {
                return _XFont;
            }
            set
            {
                _XFont = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("字体粗细")]
        [Description("FontWeight")]
        [Editor(typeof(UI.XProperty.Editors.XFontWeightEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "FontWeight", "字体粗细")]
        public FontWeight XFontWeight
        {
            get
            {
                return _XFontWeight;
            }
            set
            {
                _XFontWeight = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("图片边距")]
        [Description("BaseImageMargin")]
        [Editor(typeof(UI.XProperty.Editors.XThicknessEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "BaseImageMargin", "图片边距")]
        public Thickness XBaseImageMargin
        {
            get
            {
                return _XBaseImageMargin;
            }
            set
            {
                _XBaseImageMargin = value;
                Refresh();
            }
        }

        [Category("其他")]
        [DisplayName("进度值")]
        [Description("Value")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "Value", "进度值")]
        public double XValue
        {
            get
            {
                return (double)GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }
        #endregion

        #region fields

        private ImageSourceFile _XBaseImageSource;
        private BrushEx _XProgressFill;
        private ImageSourceFile _XFrontImageSource;
        private double _XValue;
        private double _XMinimum;
        private double _XMaximum;
        private string _XTextFormat;
        private double? _XFontSize;
        private TextAlignment _XTextAlign;
        private HorizontalAlignment _XTextHAlign;
        private VerticalAlignment _XTextVAlign;
        private Thickness _XTextMargin;
        private System.Windows.Media.FontFamily _XFont;
        private System.Windows.FontWeight _XFontWeight;
        private Thickness _XBaseImageMargin;
        #endregion

        private static readonly DependencyProperty ValueProperty
            = DependencyProperty.Register("Value", typeof(double), typeof(CircularProgress),
            new PropertyMetadata(double.NaN, new PropertyChangedCallback(OnValuePropertyChange)));

        public CircularProgress()
        {
            XTextFormat = "{data.value}";
            XMaximum = 120;
            XMinimum = 0;
            XDataItemId = "data1";
            XDataSeriesId = "series1";
            SetDefaultDataResult();
            InitializeComponent();
        }
        private void SetDefaultDataResult()
        {
            Random random = new Random();
            ServiceProxy.DataServiceRef.DataSeries[] series = new ServiceProxy.DataServiceRef.DataSeries[1];
            ServiceProxy.DataServiceRef.DataItem[] tmpItems = new ServiceProxy.DataServiceRef.DataItem[1];
            tmpItems[0] = new ServiceProxy.DataServiceRef.DataItem();
            tmpItems[0].Id = "data1";
            tmpItems[0].Name = "data1";
            tmpItems[0].Value = (random.NextDouble() * 120).ToString("F2");

            series[0] = new ServiceProxy.DataServiceRef.DataSeries();
            series[0].Id = "series1";
            series[0].Name = "series1";
            series[0].DataItems = tmpItems;
            DataResult = new ServiceProxy.DataServiceRef.DataResult();
            DataResult.DataSeries = series;
        }
        protected override void OnInit(PartContext context)
        {
            base.OnInit(context);
        }
        protected override void OnApplyXProperty()
        {
            if (baseImage == null)
            {
                return;
            }
            base.OnApplyXProperty();

            InitCircularProgress();
        }
        protected override void OnDataItemBinding(ServiceProxy.DataServiceRef.DataItem dataItem)
        {
            double height = Convert.ToDouble(dataItem.Value) * XHeight / (XMaximum - XMinimum);

            tbText.Text = FormartText(dataItem);

            DoubleAnimation doubleAnimation
                = new DoubleAnimation(XHeight - XBaseImageMargin.Top, XHeight - height - XBaseImageMargin.Bottom,
                    new Duration(TimeSpan.FromSeconds(XDataAnimationDuration)));

            this.BeginAnimation(ValueProperty, doubleAnimation);
        }
        private static void OnValuePropertyChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CircularProgress cp = d as CircularProgress;
            cp.progress_clip.Rect = new Rect(0, (double)e.NewValue, cp.XWidth, cp.XHeight);
        }

        private void InitCircularProgress()
        {
            baseImage.Source = XBaseImageSource == null ? null : XBaseImageSource.ImageSource;
            frontImage.Source = XFrontImageSource == null ? null : XFrontImageSource.ImageSource;
            progress.Fill = XProgressFill == null ? null : XProgressFill.Brush;

            if (XFontSize != null)
            {
                tbText.FontSize = XFontSize.Value;
            }
            tbText.TextAlignment = XTextAlign;
            tbText.HorizontalAlignment = XTextHAlign;
            tbText.VerticalAlignment = XTextVAlign;
            if (XFont != null)
            {
                tbText.FontFamily = XFont;
            }
            tbText.Foreground = XForeground == null? new SolidColorBrush(Colors.Black) : XForeground.Brush;
            tbText.FontWeight = XFontWeight;
            tbText.Margin = XTextMargin;

            Rect rect = new Rect();
            rect.X = 0;
            rect.Y = XHeight;
            rect.Width = XWidth;
            rect.Height = XHeight;
            progress_clip.Rect = rect;
        }

        private string FormartText(ServiceProxy.DataServiceRef.DataItem dataItem)
        {
            Regex r = new Regex(@"{[^{}]*}");
            if (!string.IsNullOrWhiteSpace(XTextFormat))
            {
                string newText = XTextFormat;
                MatchCollection matchs = r.Matches(XTextFormat);
                foreach (Match match in matchs)
                {
                    string matchResult = match.Value.Trim(new char[] { '{', '}' });
                    if (matchResult.StartsWith("data"))
                    {
                        string[] values = matchResult.Replace("data.", "").Split(new string[] { ":" }, StringSplitOptions.None);
                        PropertyInfo[] propertyInfos = dataItem.GetType().GetProperties();
                        for (int i = 0; i < propertyInfos.Length; i++)
                        {
                            string name = propertyInfos[i].Name.ToUpper();
                            if (values[0].ToUpper().Equals(name))
                            {
                                object obj = propertyInfos[i].GetValue(dataItem);

                                if (values.Length > 1)
                                {
                                    double res = default(double);
                                    if (double.TryParse(obj.ToString(), out res))
                                    {
                                        newText = newText.Replace(match.Value, res.ToString(values[1]));
                                        break;
                                    }
                                }
                                newText = newText.Replace(match.Value, obj.ToString());
                                break;
                            }
                        }
                    }
                    else if (matchResult.StartsWith("@"))
                    {
                        string value = matchResult.TrimStart(new char[] { '@' });
                        Metadata.Parameter parameter = this.GetParameter(value);
                        if (parameter != null)
                        {
                            newText = newText.Replace(match.Value, value);
                        }
                    }
                }
                return newText.Replace("\\n", "\n");
            }
            else
            {
                return dataItem.Value;
            }
        }
    }
}
